#ifndef _SE_OPENGLSHADER_
#define _SE_OPENGLSHADER_

#include "Render/Shader.h"

namespace SE
{
    class OpenGLShader final : public Shader
	{
	private:
		U32 mRenderID;
		String mFilePath;
		String mName;

        HashMap<String, I32> mUniformLocationCache;

	public:
		OpenGLShader(const String& filepath);
		OpenGLShader(const String& name, const String& vertexSrc, const String& fragmentSrc);
		virtual ~OpenGLShader();

		virtual void bind() const override;
		virtual void unbind() const override;

		virtual void setUniformInt         (const String& name, const I32 value) override;
		virtual void setUniformIntArray    (const String& name, I32* values, const U32 count) override;
		virtual void setUniformFloat       (const String& name, const Float value) override;
		virtual void setUniformFloat2      (const String& name, const Vector2f& value) override;
		virtual void setUniformFloat3      (const String& name, const Vector3f& value) override;
		virtual void setUniformFloat4      (const String& name, const Vector4f& value) override;
		virtual void setUniformMatrix3f    (const String& name, const Matrix3f& value) override;
		virtual void setUniformMatrix4f    (const String& name, const Matrix4f& value) override;

		virtual const String& getName() const override;

	private:
		String readFile(const String& filepath);
		HashMap<U32, String> preProcess(const String& source);
        void compile(const HashMap<U32, String>& shaderSources);

        I32 getUniformLocation(const String& name);
	};
} // !namespace SE

#endif // !_SE_OPENGLSHADER_